export * from './modules/dictionary';
export * from './modules/flowable';
export * from './modules/permission';
export * from './modules/upload';
import markdownit from 'markdown-it';
import hljs from 'highlight.js';
import type {
  BaseEntity,
  FileInfo,
  ResultOne,
  ResultListWithPage,
  ResultList,
  Role,
  Result,
  ResultBoolean,
  AiChatMemory,
  AIRequest,
  AIProcedureRequest,
  AiPTProcedure
} from '@/index.d';
import { urls, useLoginUserStore, api } from '@/index';
import qs from 'qs';

type ColumnValue = string | number | boolean;

export const deleteByKeyValue = async (
  url: string,
  columnName: string,
  columnValue: ColumnValue
) => {
  const res = await api({
    method: 'delete',
    url: `${url}/deleteByKeyValue/${columnName}/${columnValue}`
  });
  if (res.status === 200 && res.data.status) {
    ElMessage.success('删除成功');
    return res.data.body;
  } else {
    ElMessage.error(res.statusText);
  }
};

export const getOneByCondition = async <T extends BaseEntity>(
  url: string,
  columnName: string,
  columnValue: ColumnValue
) => {
  try {
    const res = await api({
      method: 'get',
      url: `${url}/getOneByCondition/${columnName}/${columnValue}`
    });
    if (res.status === 200) {
      const resData: ResultOne<T> = res.data;
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

export const getOneByConditions = async <T extends BaseEntity>(url: string, data: T) => {
  try {
    const res = await api({
      method: 'post',
      url: `${url}/getOneByConditions`,
      data: qs.stringify(data)
    });
    if (res.status === 200) {
      const resData: ResultOne<T> = res.data;
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

export const validateRepeat = async <T extends BaseEntity>(url: string, data: T) => {
  try {
    const res = await api({
      method: 'post',
      url: `${url}/validateRepeat`,
      data: qs.stringify(data)
    });

    if (res.status === 200) {
      const resData: ResultBoolean = res.data;
      return resData.status;
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

export const getListByCondition = async <T extends BaseEntity>(
  url: string,
  columnName: string,
  columnValue: ColumnValue
) => {
  try {
    const res = await api({
      method: 'get',
      url: `${url}/getListByCondition/${columnName}/${columnValue}`
    });
    if (res.status === 200) {
      const resData: ResultList<T> = res.data;
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

export const getListByConditions = async <T extends BaseEntity>(
  url: string,
  queryCondition: object
) => {
  try {
    const res = await api({
      method: 'post',
      url: `${url}/getListByConditions`,
      data: qs.stringify(queryCondition)
    });
    if (res.status === 200) {
      const resData: ResultList<T> = res.data;
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

export const getListByConditionsWithPage = async <T extends BaseEntity>(
  url: string,
  queryCondition: object
) => {
  try {
    const res = await api({
      method: 'post',
      url: `${url}/getListByConditionsWithPage`,
      data: qs.stringify(queryCondition)
    });
    if (res.status === 200) {
      const resData: ResultListWithPage<T> = res.data;
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

// 新增一个对象
export const insertOne = async <T extends BaseEntity>(url: string, data: T) => {
  try {
    const { loginUser } = useLoginUserStore();
    data.creatorId = loginUser.id;
    data.updaterId = loginUser.id;
    const res = await api({
      method: 'post',
      url,
      data: qs.stringify(data)
    });
    if (res.status === 200) {
      const resData: ResultOne<T> = res.data;
      ElMessage({
        message: resData.msg,
        type: resData.type
      });
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

// 修改对象
export const updateOne = async <T extends BaseEntity>(url: string, data: T) => {
  try {
    const { loginUser } = useLoginUserStore();
    data.updaterId = loginUser.id;
    const res = await api({ method: 'put', url, data: qs.stringify(data) });
    if (res.status === 200) {
      const resData: ResultOne<T> = res.data;
      ElMessage({
        message: resData.msg,
        type: resData.type
      });
      if (resData.status) {
        return resData.body;
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//物理删除一个对象
export const physicalDeleteById = async (url: string, id: number | string) => {
  try {
    const res = await api({ method: 'delete', url: url + '/physical/' + id });
    if (res.status === 200) {
      const resData = res.data;
      ElMessage({
        message: resData.msg,
        type: resData.type
      });
      return resData.status;
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//逻辑删除一个对象
export const logicalDeleteById = async (url: string, id: number | string) => {
  try {
    const res = await api({ method: 'delete', url: url + '/logical/' + id });
    if (res.status === 200) {
      const resData = res.data;
      ElMessage({
        message: resData.msg,
        type: resData.type
      });
      return resData.status;
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//逻辑删除一个对象
export const activeById = async (url: string, id: number | string) => {
  try {
    const res = await api({ method: 'get', url: url + '/active/' + id });
    if (res.status === 200) {
      const resData = res.data;
      ElMessage({
        message: resData.msg,
        type: resData.type
      });
      return resData.status;
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//根据id获取一个对象
export const getById = async <T>(url: string, id: number | string) => {
  try {
    const res = await api({ method: 'get', url: `${url}/getOneByCondition/id/${id}` });
    if (res.status === 200) {
      const resData: Result<T> = res.data;
      if (resData.status) {
        return resData.body;
      } else {
        ElMessage({
          message: resData.msg,
          type: resData.type
        });
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//获得属性数据
export const getTree = async <T>(url: string) => {
  try {
    const res = await api({
      method: 'get',
      url: `${url}/tree`
    });

    if (res.status === 200) {
      const resData: Result<T[]> = res.data;
      if (resData.status) {
        return resData.body;
      } else {
        ElMessage({
          message: resData.msg,
          type: resData.type
        });
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

// 根据条件查找一个
export const getOneByPostCondition = async <T extends BaseEntity>(url: string, data: object) => {
  try {
    const res = await api({
      method: 'post',
      url,
      data: qs.stringify(data)
    });
    if (res.status === 200) {
      const resData: ResultOne<T> = res.data;
      if (resData.status) {
        return resData.body;
      } else {
        ElMessage({
          message: resData.msg,
          type: resData.type
        });
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//根据id下载一个对象
export const downloadFileById = async (id: number) => {
  try {
    const res = await api({
      method: 'get',
      url: 'files/id/' + id
    });
    const resData: ResultOne<FileInfo> = res.data;
    if (res.status === 200) {
      //会闪屏
      //window.open(resData.object?.url);
      const iframe = document.createElement('iframe');
      iframe.src = resData.body?.url as string;
      iframe.style.display = 'none';
      document.body.appendChild(iframe);
      setTimeout(() => {
        document.body.removeChild(iframe);
      }, 1000);
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('下载失败，错误信息是：' + error);
    return false;
  }
};

//查询用户拥有的角色
export const listRolesByUserId = async (useId: number) => {
  try {
    const res = await api({
      method: 'get',
      url: `${urls.role}/user/${useId}`
    });
    if (res.status === 200) {
      const resData: ResultList<Role> = res.data;
      if (resData.status) {
        return resData.body;
      } else {
        ElMessage({
          message: resData.msg,
          type: resData.type
        });
      }
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

//根据url导出文件
export const exportToExcel = (url: string) => {
  api({
    url: `${url}/exportToExcel`,
    method: 'get',
    responseType: 'blob'
  });
};

export const cloneOperation = async (sourceId: number, targetId: number) => {
  if (!sourceId || !targetId) {
    ElMessage.error('源或目标不能为空');
    return false;
  }
  if (sourceId === targetId) {
    ElMessage.error('源与目标不能相同');
    return false;
  }
  const res = await api({
    url: `${urls.techniquePtTechnique}/clone/${sourceId}/${targetId}`
  });
  if (res.data.status) {
    ElMessage.success('克隆完成');
  } else {
    ElMessage.error(res.data.msg);
  }
  return res.data.status;
};

// 从采购产品中获取生产令号清单
export const getProductionReferenceListFromPurchaseProduction = async () => {
  try {
    const res = await api({
      method: 'get',
      url: `${urls.purchaseProduction}/productionReferenceList`
    });
    if (res.status === 200) {
      return res.data.body as string[];
    } else {
      ElMessage.error(res.statusText);
    }
  } catch (error) {
    ElMessage.error('获取失败，错误信息是：' + error);
  }
};

export const getMemoryListByUsername = async (method?: 'PT' | 'MT' | 'RT' | 'ET' | 'UT') => {
  const { loginUser } = useLoginUserStore();
  const res = await api({
    method: 'get',
    url: '/ai/memory/getMemoryListByUsername',
    // params: { username: 'admin' }
    params: { username: loginUser.username + '' + (method ? '-' + method : '') }
  });
  if (res.status === 200) {
    return res.data as Array<AiChatMemory>;
  } else {
    ElMessage.error(res.statusText);
  }
};

export const getMemoryByChatId = async (chatId: string) => {
  const res = await api({
    method: 'get',
    url: '/ai/memory/getMemoryByChatId',
    params: { chatId }
  });
  if (res.status === 200) {
    return res.data;
  } else {
    ElMessage.error(res.statusText);
  }
};

export const deleteByConversationIdStartsWithUserName = async () => {
  const res = await api({
    method: 'delete',
    url: '/ai/memory/deleteByConversationIdStartsWithUserName',
    params: { username: useLoginUserStore().loginUser.username }
  });
  if (res.status === 200) {
    ElMessage.success('删除成功');
  } else {
    ElMessage.error(res.statusText);
  }
};

export const mdTool = markdownit({
  highlight: (str: string, lang: string, attrs: string) => {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(lang, str).value;
      } catch (__) {}
    }
    return ''; // 使用额外的默认转义
  },
  html: true,
  linkify: true,
  typographer: true
});

let controller: AbortController;
export const getStreamText = async (
  url: string,
  aIRequest: AIRequest,
  clearResponse: boolean = true
): Promise<string> => {
  if (aIRequest.userMessage.trim() === '') {
    ElMessage({
      message: '请输入内容后再提交',
      type: 'error'
    });
    return '请输入内容后再提交';
  }
  aIRequest.aiLoading = true;
  aIRequest.response = '';
  controller = new AbortController();
  const signal = controller.signal;
  const res = await fetch(url, {
    method: 'POST',
    signal,
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(aIRequest)
  });
  if (!res.ok) {
    throw new Error(`HTTP error! status: ${res.status}`);
  }

  const reader = res.body?.getReader();

  if (!reader) {
    throw new Error('No reader available');
  }

  const decoder = new TextDecoder();
  let result = '';
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      result += decoder.decode(value, { stream: true });
      aIRequest.response = mdTool.render(result);
    }
  } finally {
    reader.releaseLock();
    aIRequest.aiLoading = false;
    aIRequest.userMessage = '';
    clearResponse && (aIRequest.response = '');
  }
  return result;
};

export const getPtProcedure = async (
  aIProcedureRequest: AIProcedureRequest,
  ptProcedure: AiPTProcedure
) => {
  if (aIProcedureRequest.userMessage.trim() === '') {
    ElMessage({
      message: '请输入内容后再提交',
      type: 'error'
    });
    return '请输入内容后再提交';
  }
  aIProcedureRequest.aiLoading = true;
  aIProcedureRequest.response = '';
  const res = await api({
    method: 'post',
    url: '/ai/chat/ptProcedure',
    headers: {
      'Content-Type': 'application/json'
    },

    data: JSON.stringify(aIProcedureRequest)
  });
  const data = res.data as AiPTProcedure;
  ptProcedure.temperatureUp = data.temperatureUp;
  ptProcedure.penetrationDwellTimeUp = data.penetrationDwellTimeUp;
  ptProcedure.penetrationDwellTimeDown = data.penetrationDwellTimeDown;
  ptProcedure.penetrationSetManufacturer = data.penetrationSetManufacturer;
  ptProcedure.penetrationName = data.penetrationName;
  ptProcedure.cleanerName = data.cleanerName;
  ptProcedure.developerName = data.developerName;
  aIProcedureRequest.aiLoading = false;
  aIProcedureRequest.userMessage = '';
};

export const stopAbort = () => {
  controller?.abort();
};
